<?php

Class PurchasePlusUpgradePayment extends Payment {
    private static $singular_name = "E-Purchase + E-Upgrade Payment";
    private static $plural_name = "E-Purchase + E-Upgrade Payments";
	// manual | auto
    private static $type = 'manual';
    private static $purchase_min_percentage = 0.5;
	private static $purchase_max_percentage = 1;
	private static $priority_payment = 'PurchaseAccount';
    private static $db = array(
    	'BeforePurchaseBalance' => 'Currency',
        'AfterPurchaseBalance' => 'Currency',
        'PurchaseAmount' => 'Currency',
        'BeforeUpgradeBalance' => 'Currency',
        'AfterUpgradeBalance' => 'Currency',
        'UpgradeAmount'  => 'Currency'
    );
	
	private static $many_many = array(
		'PurchaseAccounts' => 'PurchaseAccount',
		'UpgradeAccounts' => 'UpgradeAccount'
	);
	
	public function fieldLabels($includerelations = true) {
		$labels = parent::fieldLabels($includerelations);
		
		$labels['BeforePurchaseBalance'] = _t('PurchasePlusUpgradePayment.PURCHASE_BEFORE_BALANCE', 'E-Purchase Before Balance');
		$labels['AfterPurchaseBalance'] = _t('PurchasePlusUpgradePayment.PURCHASE_AFTER_BALANCE', 'E-Purchase After Balance');
		$labels['PurchaseAmount'] = _t('PurchasePlusUpgradePayment.PURCHASE_PAID_AMOUNT', 'E-Purchase Paid Amount');
		$labels['BeforeUpgradeBalance'] = _t('PurchasePlusUpgradePayment.UPGRADE_BEFORE_BALANCE', 'E-Upgrade Before Balance');
		$labels['AfterUpgradeBalance'] = _t('PurchasePlusUpgradePayment.UPGRADE_AFTER_BALANCE', 'E-Upgrade After Balance');
		$labels['UpgradeAmount'] = _t('PurchasePlusUpgradePayment.UPGRADE_PAID_AMOUNT', 'E-Upgrade Paid Amount');
		
		return $labels;	
	}
	
	function validate() {
        $validationResult = parent::validate();

		if($this->isChanged('Status') && $this->Status == 'Success'){
			$data = array(
				'MemberID' => $this->Receipt()->MemberID,
				'Amount' => $this->Amount,
				'PurchasePlusUpgradePayment_PurchaseAmount' => $this->PurchaseAmount,
				'PurchasePlusUpgradePayment_UpgradeAmount' => $this->UpgradeAmount
			);
	        $errors = $this->getPaymentFormRequirements(RequiredFields::create(), $data)->getErrors();

			if($errors){
	        	foreach($errors as $error){
            		$validationResult->error($error['message']);
				}
            }
		}

        return $validationResult;
    }
    
    function getCMSFields(){
        $fields = parent::getCMSFields();

		$fields->makeFieldReadonly('BeforePurchaseBalance');
        $fields->makeFieldReadonly('AfterPurchaseBalance');
        $fields->makeFieldReadonly('BeforeUpgradeBalance');
        $fields->makeFieldReadonly('AfterUpgradeBalance');
		$fields->removeByName('PurchaseAccounts');
		$fields->removeByName('UpgradeAccounts');
        
        return $fields;
    }
    
    function getPaymentFormFields($memberid){
    	$purchase_payment = $this->Amount * $this->config()->get('purchase_min_percentage');
    	$upgrade_payment = $this->Amount * (1 - $this->config()->get('purchase_min_percentage'));
    	if($this->config()->get('priority_payment') == 'PurchaseAccount'){
			$purchase_balance = Account::get('PurchaseAccount', $memberid)->Balance;
			if($purchase_balance > $purchase_payment){
		    	if($this->Amount * $this->config()->get('purchase_max_percentage') < $purchase_balance){
					$purchase_payment = $this->Amount * $this->config()->get('purchase_max_percentage');
				}
				else{
					$purchase_payment = $purchase_balance;
				}
			}

			$upgrade_payment = $this->Amount - $purchase_payment;
		}
		else{
			$upgrade_balance = Account::get('UpgradeAccount', $memberid)->Balance;
	    	if($upgrade_balance < $upgrade_payment){
	    		if($upgrade_balance < $this->Amount * (1 - $this->config()->get('purchase_max_percentage'))){
	    			$upgrade_payment = $this->Amount * (1 - $this->config()->get('purchase_max_percentage'));
				}
				else{
					$upgrade_payment = $upgrade_balance;
				}
			}

			$purchase_payment = $this->Amount - $upgrade_payment;
		}
		
		$fields = FieldList::create(
        	HtmlEditorField_Readonly::create('PurchasePlusUpgradePayment_Note', _t('PurchasePlusUpgradePayment.NOTE', 'Note'), _t('PurchasePlusUpgradePayment.INVALID_PURCHASE_AMOUNT', 'E-Purchase payment amount cannot less than {min_percentage} or exceed {max_percentage} of total payment amount', '', array('min_percentage' => DBField::create_field('Percentage', $this->config()->purchase_min_percentage)->Nice(), 'max_percentage' => DBField::create_field('Percentage', $this->config()->purchase_max_percentage)->Nice()))),
        	$purchaseAccountBalanceField = ReadonlyField::create('PurchasePlusUpgradePayment_ShowPlusPurchaseAccountBalance', _t('PurchasePlusUpgradePayment.CURRENT_PURCHASE_BALANCE', 'Current E-Purchase Balance'), Account::get('PurchaseAccount', $memberid)->obj('Balance')->Nice()),
            $purchaseAccountAmountField = NumericField::create('PurchasePlusUpgradePayment_PurchaseAmount', _t('PurchasePlusUpgradePayment.PURCHASE_PAYMENT_AMOUNT', 'E-Purchase Payment Amount'))->setAttribute('data-inputmask-allowminus', 'false'),
            $upgradeAccountBalanceField = ReadonlyField::create('PurchasePlusUpgradePayment_ShowPlusUpgradeAccountBalance', _t('PurchasePlusUpgradePayment.CURRENT_UPGRADE_BALANCE', 'Current E-Upgrade Balance'), Account::get('UpgradeAccount', $memberid)->obj('Balance')->Nice()),
            $upgradeAccountAmountField = NumericField::create('PurchasePlusUpgradePayment_UpgradeAmount', _t('PurchasePlusUpgradePayment.UPGRADE_PAYMENT_AMOUNT', 'E-Upgrade Payment Amount'))->setAttribute('data-inputmask-allowminus', 'false')
        );
		
    	if($this->config()->get('type') == 'auto'){
    		$purchaseAccountAmountField->setAttribute('readonly', 'readonly');
			$upgradeAccountAmountField->setAttribute('readonly', 'readonly');
    	}
		
		$purchaseAccountBalanceField->setIncludeHiddenField(true);
		$upgradeAccountBalanceField->setIncludeHiddenField(true);
		
		$this->extend('updatePaymentFormFields', $fields, $memberid);
		
        return $fields;
    }

    function getPaymentFormRequirements($validator, $data){
        if($data['MemberID'] == '' || !$member = DataObject::get_by_id('Member', (int)$data['MemberID'])){
            $validator->validationError(
                'Payment',
                _t('PurchasePlusUpgradePayment.INVALID_MEMBER_ID', 'Invalid Member ID'),
                'warning'
            );
        }
        else if($data['Amount'] <= 0){
            $validator->validationError(
                'Payment',
                _t('PurchasePlusUpgradePayment.INVALID_AMOUNT', 'Invalid Amount'),
                'warning'
            );
        }
		else if(bccomp($data['PurchasePlusUpgradePayment_PurchaseAmount'], $data['Amount'] * $thsi->config()->purchase_min_percentage) < 0 || bccomp($data['PurchasePlusUpgradePayment_PurchaseAmount'], $data['Amount'] * $thsi->config()->purchase_max_percentage) > 0){
            $validator->validationError(
                'PurchasePlusUpgradePayment_PurchaseAmount',
                _t('PurchasePlusUpgradePayment.INVALID_PURCHASE_AMOUNT', 'E-Purchase payment amount cannot less than {min_percentage} or exceed {max_percentage} of total payment amount', '', array('min_percentage' => DBField::create_field('Percentage', $this->config()->purchase_min_percentage)->Nice(), 'max_percentage' => DBField::create_field('Percentage', $this->config()->purchase_max_percentage)->Nice())),
                'warning'
            );
        }
		else if(bccomp($data['PurchasePlusUpgradePayment_PurchaseAmount'] + $data['PurchasePlusUpgradePayment_UpgradeAmount'], $data['Amount']) != 0){
            $validator->validationError(
                'Payment',
                _t('PurchasePlusUpgradePayment.INVALID_PAYMENT_AMOUNT', 'E-Purchase + E-Upgrade payment amount is not tally with total payment amount'),
                'warning'
            );
        }
		else{
			if(bccomp(Account::get('PurchaseAccount', $data['MemberID'])->Balance, $data['PurchasePlusUpgradePayment_PurchaseAmount']) < 0){
	            $validator->validationError(
	                'PurchasePlusUpgradePayment_PurchaseAmount',
	                _t('PurchasePlusUpgradePayment.INSUFFICIENT_BALANCE', 'Insufficient account balance ({balance})', 'Display insufficient account balance', array('balance' => Account::get('PurchaseAccount', $data['MemberID'])->obj('Balance')->Nice())),
	                'warning'
	            );
	        }
			
	        if(bccomp(Account::get('UpgradeAccount', $data['MemberID'])->Balance, $data['PurchasePlusUpgradePayment_UpgradeAmount']) < 0){
	            $validator->validationError(
	                'PurchasePlusUpgradePayment_UpgradeAmount',
	                _t('PurchasePlusUpgradePayment.INSUFFICIENT_BALANCE', 'Insufficient account balance ({balance})', 'Display insufficient account balance', array('balance' => Account::get('UpgradeAccount', $data['MemberID'])->obj('Balance')->Nice())),
	                'warning'
	            );
	        }
	    }
		
		$this->extend('updatePaymentFormRequirements', $validator, $data);

        return $validator;
    }

	function onBeforeWrite(){
		parent::onBeforeWrite();

		if($this->isChanged('Status') && $this->Status == 'Success'){
			if($this->PurchaseAmount > 0 && !$this->PurchaseAccounts()->filter('Debit:GreaterThan', 0)->count()){
				$this->setField('BeforePurchaseBalance', Account::get('PurchaseAccount', $this->Receipt()->MemberID)->Balance);
				$statement_data = array(
	                'Type' => 'Purchase',
	                'Debit' => $this->PurchaseAmount,
	                'Reference' => $this->Receipt()->Reference,
	                'Description' => $this->Receipt()->TransactionType()->Description
	            );
	            $id = PurchaseAccount::create_statement($statement_data, $this->Receipt()->MemberID);
				$this->setField('AfterPurchaseBalance', Account::get('PurchaseAccount', $this->Receipt()->MemberID)->Balance);
				$this->PurchaseAccounts()->add($id);
			}

			if($this->UpgradeAmount > 0 && !$this->UpgradeAccounts()->filter('Debit:GreaterThan', 0)->count()){
	            $this->setField('BeforeUpgradeBalance', Account::get('UpgradeAccount', $this->Receipt()->MemberID)->Balance);
	            $statement_data = array(
	                'Type' => 'Purchase',
	                'Debit' => $this->UpgradeAmount,
	                'Reference' => $this->Receipt()->Reference,
	                'Description' => $this->Receipt()->TransactionType()->Description
	            );
	            $id = UpgradeAccount::create_statement($statement_data, $this->Receipt()->MemberID);
	            $this->setField('AfterUpgradeBalance', Account::get('UpgradeAccount', $this->Receipt()->MemberID)->Balance);
				$this->UpgradeAccounts()->add($id);
			}
		}
	}
    
    function pendingPayment($data = array()){
        $this->update($data)->setField('Status', 'Pending')->write();
        return $this;
    }
    
    function failurePayment($data = array()){
        $this->update($data)->setField('Status', 'Failure')->write();
        return $this;
    }
    
    function completePayment($data = array()){
        if($this->Status == 'Incomplete' || $this->Status == 'Pending'){
            $this->update($data)->setField('Status', 'Success')->write();
        }
        
        return $this;
    }
    
    function ProcessLink(){
        $token = SecurityToken::inst();
        return $token->addToUrl(Controller::join_links('ewallet', 'process', $this->ID, $this->ClassName)) . sprintf('&locale=%s', Controller::curr()->Locale);
    }
	
	function checkBalance(){
		return (Account::get('PurchaseAccount', $this->Receipt()->MemberID)->Balance >= $this->PurchaseAmount) && (Account::get('UpgradeAccount', $this->Receipt()->MemberID)->Balance >= $this->UpgradeAmount);
	}
}

?>